/*
 * This file is part of Cadmium.
 * Copyright (C) 2007-2010 Xavier Clerc.
 *
 * Cadmium is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Cadmium is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package fr.x9c.cadmium.primitives.cadmiumjdbc;

import java.math.BigDecimal;
import java.net.URL;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
import java.sql.NClob;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLXML;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;

import fr.x9c.cadmium.kernel.Block;
import fr.x9c.cadmium.kernel.Channel;
import fr.x9c.cadmium.kernel.CodeRunner;
import fr.x9c.cadmium.kernel.Custom;
import fr.x9c.cadmium.kernel.Fail;
import fr.x9c.cadmium.kernel.Primitive;
import fr.x9c.cadmium.kernel.PrimitiveProvider;
import fr.x9c.cadmium.kernel.Value;
import fr.x9c.cadmium.primitives.cadmium.Cadmium;

/**
 * This class provides the primitives related to the <tt>java.sql.PreparedStatement</tt> class.
 *
 * @author <a href="mailto:cadmium@x9c.fr">Xavier Clerc</a>
 * @version 1.1
 * @since 1.1
 */
@PrimitiveProvider
public final class PreparedStatements {

    /**
     * No instance of this class.
     */
    private PreparedStatements() {
    } // end empty constructor

    /**
     * Adds a set of parameters to the passed prepared statement.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_add_batch(final CodeRunner ctxt,
                                                                final Value preparedStatement)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            ps.addBatch();
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_add_batch(CodeRunner, Value)'

    /**
     * Clears the parmeter values of the passed prepared statement.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_clear_parameters(final CodeRunner ctxt,
                                                                       final Value preparedStatement)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            ps.clearParameters();
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_clear_parameters(CodeRunner, Value)'

    /**
     * Executes the SQL statement associated with the passed prepared statement.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @return <tt>true</tt> if the first result is a result set object,
     *         <tt>false</tt> otherwise (update count of absence of result)
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_execute(final CodeRunner ctxt,
                                                              final Value preparedStatement)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            return ps.execute() ? Value.TRUE : Value.FALSE;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_execute(CodeRunner, Value)'

    /**
     * Executes the SQL query associated with the passed prepared statement.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @return query result set
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_execute_query(final CodeRunner ctxt,
                                                                    final Value preparedStatement)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            final ResultSet res = ps.executeQuery();
            return Cadmium.createObject(res);
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_execute_query(CodeRunner, Value)'

    /**
     * Executes the SQL statement associated with the passed prepared statement
     * (either a <i>INSERT</i>, <i>UPDATE</i> or <i>DELETE</i> query).
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @return update count
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_execute_update(final CodeRunner ctxt,
                                                                     final Value preparedStatement)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            final Block res = Block.createCustom(Custom.INT_32_SIZE,
                                                 Custom.INT_32_OPS);
            res.setInt32(ps.executeUpdate());
            return Value.createFromBlock(res);
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_execute_update(CodeRunner, Value)'

    /**
     * Returns the result set metadata associated for the passed prepared statement.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @return the result set metadata associated for the passed prepared statement
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_get_meta_data(final CodeRunner ctxt,
                                                                    final Value preparedStatement)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            final ResultSetMetaData res = ps.getMetaData();
            return Cadmium.createObject(res);
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_get_meta_data(CodeRunner, Value)'

    /**
     * Returns the parameter metadata associated for the passed prepared statement.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @return the parameter metadata associated for the passed prepared statement
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_get_parameter_meta_data(final CodeRunner ctxt,
                                                                              final Value preparedStatement)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            final ParameterMetaData res = ps.getParameterMetaData();
            return Cadmium.createObject(res);
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_get_parameter_meta_data(CodeRunner, Value)'

    /**
     * Sets the parameter at the given index to an array value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_array_idx(final CodeRunner ctxt,
                                                                    final Value preparedStatement,
                                                                    final Value idx,
                                                                    final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setArray(idx.asLong(),
                            (Array) x.asBlock().get(0).asBlock().asCustom());
            } else {
                ps.setNull(idx.asLong(), Types.ARRAY);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_array_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to an ASCII stream.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_ascii_stream_idx(final CodeRunner ctxt,
                                                                           final Value preparedStatement,
                                                                           final Value idx,
                                                                           final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                final Channel ch = (Channel) x.asBlock().get(0).asBlock().asCustom();
                ps.setAsciiStream(idx.asLong(), ch.asInputStream());
            } else {
                ps.setNull(idx.asLong(), Types.LONGVARCHAR);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_ascii_stream_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to an ASCII stream.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @param length stream length
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_ascii_stream_length_idx(final CodeRunner ctxt,
                                                                                  final Value preparedStatement,
                                                                                  final Value idx,
                                                                                  final Value x,
                                                                                  final Value length)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                final Channel ch = (Channel) x.asBlock().get(0).asBlock().asCustom();
                ps.setAsciiStream(idx.asLong(), ch.asInputStream(),
                                  length.asBlock().asInt32());
            } else {
                ps.setNull(idx.asLong(), Types.LONGVARCHAR);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_ascii_stream_length_idx(CodeRunner, Value, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to an ASCII stream.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @param length stream length
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_ascii_stream_length64_idx(final CodeRunner ctxt,
                                                                                    final Value preparedStatement,
                                                                                    final Value idx,
                                                                                    final Value x,
                                                                                    final Value length)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                final Channel ch = (Channel) x.asBlock().get(0).asBlock().asCustom();
                ps.setAsciiStream(idx.asLong(), ch.asInputStream(),
                                  length.asBlock().asInt64());
            } else {
                ps.setNull(idx.asLong(), Types.LONGVARCHAR);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_ascii_stream_length64_idx(CodeRunner, Value, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a big decimal value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_big_decimal_idx(final CodeRunner ctxt,
                                                                          final Value preparedStatement,
                                                                          final Value idx,
                                                                          final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setBigDecimal(idx.asLong(),
                                 (BigDecimal) x.asBlock().get(0).asBlock().asCustom());
            } else {
                ps.setNull(idx.asLong(), Types.NUMERIC);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_big_decimal_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a binary stream.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_binary_stream_idx(final CodeRunner ctxt,
                                                                            final Value preparedStatement,
                                                                            final Value idx,
                                                                            final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                final Channel ch = (Channel) x.asBlock().get(0).asBlock().asCustom();
                ps.setBinaryStream(idx.asLong(), ch.asInputStream());
            } else {
                ps.setNull(idx.asLong(), Types.LONGVARBINARY);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_binary_stream_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a binary stream.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @param length stream length
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_binary_stream_length_idx(final CodeRunner ctxt,
                                                                                   final Value preparedStatement,
                                                                                   final Value idx,
                                                                                   final Value x,
                                                                                   final Value length)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                final Channel ch = (Channel) x.asBlock().get(0).asBlock().asCustom();
                ps.setBinaryStream(idx.asLong(), ch.asInputStream(),
                                   length.asBlock().asInt32());
            } else {
                ps.setNull(idx.asLong(), Types.LONGVARBINARY);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_binary_stream_length_idx(CodeRunner, Value, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a binary stream.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @param length stream length
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_binary_stream_length64_idx(final CodeRunner ctxt,
                                                                                     final Value preparedStatement,
                                                                                     final Value idx,
                                                                                     final Value x,
                                                                                     final Value length)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                final Channel ch = (Channel) x.asBlock().get(0).asBlock().asCustom();
                ps.setBinaryStream(idx.asLong(), ch.asInputStream(),
                                   length.asBlock().asInt64());
            } else {
                ps.setNull(idx.asLong(), Types.LONGVARBINARY);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_binary_stream_length64_idx(CodeRunner, Value, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a blob value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_blob_idx(final CodeRunner ctxt,
                                                                   final Value preparedStatement,
                                                                   final Value idx,
                                                                   final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setBlob(idx.asLong(),
                           (Blob) x.asBlock().get(0).asBlock().asCustom());
            } else {
                ps.setNull(idx.asLong(), Types.BLOB);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_blob_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a boolean value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_boolean_idx(final CodeRunner ctxt,
                                                                      final Value preparedStatement,
                                                                      final Value idx,
                                                                      final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setBoolean(idx.asLong(),
                              x.asBlock().get(0) == Value.TRUE);
            } else {
                ps.setNull(idx.asLong(), Types.BOOLEAN);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_boolean_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a byte value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_byte_idx(final CodeRunner ctxt,
                                                                   final Value preparedStatement,
                                                                   final Value idx,
                                                                   final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setByte(idx.asLong(), (byte) x.asBlock().get(0).asLong());
            } else {
                ps.setNull(idx.asLong(), Types.TINYINT);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_byte_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a byte array value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_bytes_idx(final CodeRunner ctxt,
                                                                    final Value preparedStatement,
                                                                    final Value idx,
                                                                    final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setBytes(idx.asLong(), x.asBlock().get(0).asBlock().getBytes());
            } else {
                try {
                    ps.setNull(idx.asLong(), Types.VARBINARY);
                } catch (final SQLException se) {
                    ps.setNull(idx.asLong(), Types.LONGVARBINARY);
                } // end try/catch
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_bytes_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a clob value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_clob_idx(final CodeRunner ctxt,
                                                                   final Value preparedStatement,
                                                                   final Value idx,
                                                                   final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setClob(idx.asLong(),
                           (Clob) x.asBlock().get(0).asBlock().asCustom());
            } else {
                ps.setNull(idx.asLong(), Types.CLOB);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_clob_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a date value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_date_idx(final CodeRunner ctxt,
                                                                   final Value preparedStatement,
                                                                   final Value idx,
                                                                   final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setDate(idx.asLong(),
                           (Date) x.asBlock().get(0).asBlock().asCustom());
            } else {
                ps.setNull(idx.asLong(), Types.DATE);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_date_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a double value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_double_idx(final CodeRunner ctxt,
                                                                     final Value preparedStatement,
                                                                     final Value idx,
                                                                     final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setDouble(idx.asLong(),
                             x.asBlock().get(0).asBlock().asDouble());
            } else {
                ps.setNull(idx.asLong(), Types.DOUBLE);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_double_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a float value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_float_idx(final CodeRunner ctxt,
                                                                    final Value preparedStatement,
                                                                    final Value idx,
                                                                    final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setFloat(idx.asLong(),
                            (float) x.asBlock().get(0).asBlock().asDouble());
            } else {
                ps.setNull(idx.asLong(), Types.REAL);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_float_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to an int value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_int_idx(final CodeRunner ctxt,
                                                                  final Value preparedStatement,
                                                                  final Value idx,
                                                                  final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setInt(idx.asLong(),
                          x.asBlock().get(0).asBlock().asInt32());
            } else {
                ps.setNull(idx.asLong(), Types.INTEGER);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_int_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a long value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_long_idx(final CodeRunner ctxt,
                                                                   final Value preparedStatement,
                                                                   final Value idx,
                                                                   final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setLong(idx.asLong(),
                           x.asBlock().get(0).asBlock().asInt64());
            } else {
                ps.setNull(idx.asLong(), Types.BIGINT);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_long_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a nclob value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_nclob_idx(final CodeRunner ctxt,
                                                                    final Value preparedStatement,
                                                                    final Value idx,
                                                                    final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setNClob(idx.asLong(),
                            (NClob) x.asBlock().get(0).asBlock().asCustom());
            } else {
                ps.setNull(idx.asLong(), Types.NCLOB);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_nclob_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a nstring value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_nstring_idx(final CodeRunner ctxt,
                                                                      final Value preparedStatement,
                                                                      final Value idx,
                                                                      final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setNString(idx.asLong(),
                              x.asBlock().get(0).asBlock().asString());
            } else {
                try {
                    ps.setNull(idx.asLong(), Types.NCHAR);
                } catch (final SQLException se1) {
                    try {
                        ps.setNull(idx.asLong(), Types.NVARCHAR);
                    } catch (final SQLException se2) {
                        ps.setNull(idx.asLong(), Types.LONGNVARCHAR);
                    } // end try/catch
                } // end try/catch
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_nstring_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to an object value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_object_idx(final CodeRunner ctxt,
                                                                     final Value preparedStatement,
                                                                     final Value idx,
                                                                     final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setObject(idx.asLong(),
                             x.asBlock().get(0).asBlock().asCustom());
            } else {
                ps.setNull(idx.asLong(), Types.JAVA_OBJECT);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_object_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to an object value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @param type JDBC type the passed object value should be mapped to
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_object_type_idx(final CodeRunner ctxt,
                                                                          final Value preparedStatement,
                                                                          final Value idx,
                                                                          final Value x,
                                                                          final Value type)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setObject(idx.asLong(),
                             x.asBlock().get(0).asBlock().asCustom(),
                             Misc.decodeJDBCType(type));
            } else {
                ps.setNull(idx.asLong(), Types.JAVA_OBJECT);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_object_type_idx(CodeRunner, Value, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to an object value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @param type JDBC type the passed object value should be mapped to
     * @param scale scale of length the passed object value should be converted to
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_object_type_scale_idx(final CodeRunner ctxt,
                                                                                final Value preparedStatement,
                                                                                final Value idx,
                                                                                final Value x,
                                                                                final Value type,
                                                                                final Value scale)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setObject(idx.asLong(),
                             x.asBlock().get(0).asBlock().asCustom(),
                             Misc.decodeJDBCType(type),
                             scale.asLong());
            } else {
                ps.setNull(idx.asLong(), Types.JAVA_OBJECT);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_object_type_scale_idx(CodeRunner, Value, Value, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a reference value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_ref_idx(final CodeRunner ctxt,
                                                                  final Value preparedStatement,
                                                                  final Value idx,
                                                                  final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setRef(idx.asLong(),
                          (Ref) x.asBlock().get(0).asBlock().asCustom());
            } else {
                ps.setNull(idx.asLong(), Types.REF);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_ref_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a row id value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_row_id_idx(final CodeRunner ctxt,
                                                                     final Value preparedStatement,
                                                                     final Value idx,
                                                                     final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setRowId(idx.asLong(),
                            (RowId) x.asBlock().get(0).asBlock().asCustom());
            } else {
                ps.setNull(idx.asLong(), Types.ROWID);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_row_id_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a short value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_short_idx(final CodeRunner ctxt,
                                                                    final Value preparedStatement,
                                                                    final Value idx,
                                                                    final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setShort(idx.asLong(),
                            (short) x.asBlock().get(0).asLong());
            } else {
                ps.setNull(idx.asLong(), Types.SMALLINT);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_short_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a SQL XML value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_sqlxml_idx(final CodeRunner ctxt,
                                                                     final Value preparedStatement,
                                                                     final Value idx,
                                                                     final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setSQLXML(idx.asLong(),
                             (SQLXML) x.asBlock().get(0).asBlock().asCustom());
            } else {
                ps.setNull(idx.asLong(), Types.SQLXML);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_sqlxml_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a string value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_string_idx(final CodeRunner ctxt,
                                                                     final Value preparedStatement,
                                                                     final Value idx,
                                                                     final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setString(idx.asLong(),
                             x.asBlock().get(0).asBlock().asString());
            } else {
                try {
                    ps.setNull(idx.asLong(), Types.VARCHAR);
                } catch (final SQLException se) {
                    ps.setNull(idx.asLong(), Types.LONGVARCHAR);
                } // end try/catch
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_string_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a time value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_time_idx(final CodeRunner ctxt,
                                                                   final Value preparedStatement,
                                                                   final Value idx,
                                                                   final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setTime(idx.asLong(),
                           (Time) x.asBlock().get(0).asBlock().asCustom());
            } else {
                ps.setNull(idx.asLong(), Types.TIME);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_time_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a timestamp value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_timestamp_idx(final CodeRunner ctxt,
                                                                        final Value preparedStatement,
                                                                        final Value idx,
                                                                        final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setTimestamp(idx.asLong(),
                                (Timestamp) x.asBlock().get(0).asBlock().asCustom());
            } else {
                ps.setNull(idx.asLong(), Types.TIMESTAMP);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_timestamp_idx(CodeRunner, Value, Value, Value)'

    /**
     * Sets the parameter at the given index to a URL value.
     * @param ctxt context
     * @param preparedStatement prepared statement
     * @param idx parameter index
     * @param x parameter value
     * @return <i>unit</i>
     * @throws Fail.Exception if any error occurs
     */
    @Primitive
    public static Value cadmiumjdbc_preparedstatement_set_url_idx(final CodeRunner ctxt,
                                                                  final Value preparedStatement,
                                                                  final Value idx,
                                                                  final Value x)
        throws Fail.Exception {
        try {
            final PreparedStatement ps =
                (PreparedStatement) preparedStatement.asBlock().asCustom();
            if (x.isBlock()) {
                ps.setURL(idx.asLong(),
                          new URL(x.asBlock().get(0).asBlock().asString()));
            } else {
                ps.setNull(idx.asLong(), Types.DATALINK);
            } // end if/else
            return Value.UNIT;
        } catch (final Exception e) {
            Cadmium.fail(ctxt, e);
            return Value.UNIT; // never reached
        } // end try/catch
    } // end method 'cadmiumjdbc_preparedstatement_set_url_idx(CodeRunner, Value, Value, Value)'

} // end class 'PreparedStatements'
